package zy.service.buy.fee.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import zy.dao.approve.ApproveRecordDAO;
import zy.dao.buy.dealings.BuyDealingsDAO;
import zy.dao.buy.fee.BuyFeeDAO;
import zy.dao.buy.settle.BuySettleDAO;
import zy.dao.buy.supply.SupplyDAO;
import zy.dao.sys.print.PrintDAO;
import zy.dto.buy.fee.BuyFeeReportDto;
import zy.entity.PageData;
import zy.entity.PageInfo;
import zy.entity.approve.T_Approve_Record;
import zy.entity.buy.dealings.T_Buy_Dealings;
import zy.entity.buy.fee.T_Buy_Fee;
import zy.entity.buy.fee.T_Buy_FeeList;
import zy.entity.buy.settle.T_Buy_SettleList;
import zy.entity.buy.supply.T_Buy_Supply;
import zy.entity.sys.user.T_Sys_User;
import zy.service.buy.fee.BuyFeeService;
import zy.util.CommonUtil;
import zy.util.DateUtil;
import zy.util.StringUtil;

@Service
public class BuyFeeServiceImpl implements BuyFeeService{
	@Resource
	private BuyFeeDAO buyFeeDAO;
	@Resource
	private ApproveRecordDAO approveRecordDAO;
	@Resource
	private BuyDealingsDAO buyDealingsDAO;
	@Resource
	private BuySettleDAO buySettleDAO;
	@Resource
	private SupplyDAO supplyDAO;
	@Resource
	private PrintDAO printDAO;
	
	@Override
	public PageData<T_Buy_Fee> page(Map<String, Object> params) {
		Integer pageSize = (Integer)params.get(CommonUtil.PAGESIZE);
		Integer pageIndex = (Integer)params.get(CommonUtil.PAGEINDEX);
		
		Integer totalCount = buyFeeDAO.count(params);
		PageInfo pageInfo = new PageInfo(totalCount, pageSize, pageIndex);
		params.put(CommonUtil.START, (pageIndex-1)*pageSize);
		params.put(CommonUtil.END, pageSize);
		
		List<T_Buy_Fee> list = buyFeeDAO.list(params);
		PageData<T_Buy_Fee> pageData = new PageData<T_Buy_Fee>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@Override
	public T_Buy_Fee load(Integer fe_id) {
		T_Buy_Fee fee = buyFeeDAO.load(fe_id);
		if(fee != null){
			T_Approve_Record approve_Record = approveRecordDAO.load(fee.getFe_number(), fee.getCompanyid());
			if(approve_Record != null){
				fee.setAr_describe(approve_Record.getAr_describe());
			}
		}
		return fee;
	}
	
	@Override
	public T_Buy_Fee load(String number,Integer companyid) {
		return buyFeeDAO.load(number,companyid);
	}
	
	@Override
	public List<T_Buy_FeeList> temp_list(Map<String, Object> params) {
		return buyFeeDAO.temp_list(params);
	}
	
	@Override
	@Transactional
	public void temp_save(List<T_Buy_FeeList> temps,T_Sys_User user) {
		if (temps == null || temps.size() == 0) {
			throw new RuntimeException("请选择费用类型");
		}
		List<String> existCode = buyFeeDAO.temp_check(user.getUs_id(),user.getCompanyid());
		List<T_Buy_FeeList> temps_add = new ArrayList<T_Buy_FeeList>();
		for (T_Buy_FeeList temp : temps) {
			if(!existCode.contains(temp.getFel_mp_code())){
				temp.setFel_us_id(user.getUs_id());
				temp.setFel_remark("");
				temp.setCompanyid(user.getCompanyid());
				temps_add.add(temp);
			}
		}
		if (temps_add.size() > 0) {
			buyFeeDAO.temp_save(temps_add);
		}
	}
	
	@Override
	@Transactional
	public void temp_updateMoney(T_Buy_FeeList temp) {
		buyFeeDAO.temp_updateMoney(temp);
	}
	
	@Override
	@Transactional
	public void temp_updateRemark(T_Buy_FeeList temp) {
		buyFeeDAO.temp_updateRemark(temp);
	}
	
	@Override
	@Transactional
	public void temp_del(Integer fel_id) {
		buyFeeDAO.temp_del(fel_id);
	}
	
	@Override
	@Transactional
	public void temp_clear(Integer us_id,Integer companyid) {
		buyFeeDAO.temp_clear(us_id, companyid);;
	}
	
	@Override
	public List<T_Buy_FeeList> detail_list(Map<String, Object> params) {
		return buyFeeDAO.detail_list(params);
	}
	
	@Override
	@Transactional
	public void save(T_Buy_Fee fee, T_Sys_User user) {
		if(fee == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(fee.getFe_supply_code())){
			throw new IllegalArgumentException("供货厂商不能为空");
		}
		if(StringUtil.isEmpty(fee.getFe_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		fee.setCompanyid(user.getCompanyid());
		fee.setFe_us_id(user.getUs_id());
		fee.setFe_maker(user.getUs_name());
		fee.setFe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		fee.setFe_sysdate(DateUtil.getCurrentTime());
		fee.setFe_pay_state(0);
		//1.查临时表
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fel_us_id", user.getUs_id());
		params.put("companyid", user.getCompanyid());
		List<T_Buy_FeeList> temps = buyFeeDAO.temp_list(params);
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//2.保存单据
		double fe_money = 0d;
		for (T_Buy_FeeList temp : temps) {
			if(temp.getFel_money().doubleValue() == 0d){
				throw new RuntimeException("明细数据存在为0的费用类型，请修改");
			}
			fe_money += temp.getFel_money();
		}
		fee.setFe_money(fe_money);
		fee.setFe_discount_money(0d);
		fee.setFe_payable(fe_money);
		fee.setFe_payabled(0d);
		fee.setFe_prepay(0d);
		buyFeeDAO.save(fee, temps);
		//3.删除临时表
		buyFeeDAO.temp_clear(user.getUs_id(), user.getCompanyid());
	}
	
	@Override
	@Transactional
	public void update(T_Buy_Fee fee, T_Sys_User user) {
		if(fee == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(fee.getFe_supply_code())){
			throw new IllegalArgumentException("供货厂商不能为空");
		}
		if(StringUtil.isEmpty(fee.getFe_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		fee.setCompanyid(user.getCompanyid());
		fee.setFe_us_id(user.getUs_id());
		fee.setFe_maker(user.getUs_name());
		fee.setFe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		fee.setFe_sysdate(DateUtil.getCurrentTime());
		fee.setFe_pay_state(0);
		//1.1查临时表
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fel_us_id", user.getUs_id());
		params.put("companyid", user.getCompanyid());
		List<T_Buy_FeeList> temps = buyFeeDAO.temp_list(params);
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//1.2验证单据
		T_Buy_Fee oldFee = buyFeeDAO.check(fee.getFe_number(), user.getCompanyid());
		if (oldFee == null || !CommonUtil.AR_STATE_FAIL.equals(oldFee.getFe_ar_state())) {
			throw new RuntimeException("单据已修改，请勿重复提交");
		}
		//2.保存单据
		double fe_money = 0d;
		for (T_Buy_FeeList temp : temps) {
			if(temp.getFel_money().doubleValue() == 0d){
				throw new RuntimeException("明细数据存在为0的费用类型，请修改");
			}
			fe_money += temp.getFel_money();
		}
		fee.setFe_money(fe_money);
		fee.setFe_discount_money(0d);
		fee.setFe_payable(fe_money);
		fee.setFe_payabled(0d);
		fee.setFe_prepay(0d);
		buyFeeDAO.deleteList(fee.getFe_number(), user.getCompanyid());
		buyFeeDAO.update(fee, temps);
		//3.删除临时表
		buyFeeDAO.temp_clear(user.getUs_id(), user.getCompanyid());
	}
	
	@Override
	@Transactional
	public T_Buy_Fee approve(String number, T_Approve_Record record, T_Sys_User user) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Buy_Fee fee = buyFeeDAO.check(number, user.getCompanyid());
		if(fee == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(fee.getFe_ar_state())){
			throw new RuntimeException("单据已经审核");
		}
		//更新单据审核状态
		fee.setFe_ar_state(record.getAr_state());
		fee.setFe_ar_date(DateUtil.getCurrentTime());
		buyFeeDAO.updateApprove(fee);
		//保存审核记录表
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_buy_fee");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		if(!CommonUtil.AR_STATE_APPROVED.equals(fee.getFe_ar_state())){//审核不通过，则直接返回
			return fee;
		}
		//3.审核通过
		//3.1更新供应商财务&生成往来明细账
		T_Buy_Supply supply = supplyDAO.loadSupply(fee.getFe_supply_code(), user.getCompanyid());
		if (supply != null) {
			supply.setSp_payable(supply.getSp_payable() + fee.getFe_payable());
			supplyDAO.updatePayable(supply);
			T_Buy_Dealings dealings = new T_Buy_Dealings();
			dealings.setDl_supply_code(fee.getFe_supply_code());
			dealings.setDl_number(fee.getFe_number());
			dealings.setDl_type(CommonUtil.BUYDEALINGS_TYPE_FY);
			dealings.setDl_discount_money(fee.getFe_discount_money());
			dealings.setDl_payable(fee.getFe_payable());
			dealings.setDl_payabled(0d);
			dealings.setDl_debt(supply.getSp_payable()-supply.getSp_payabled()-supply.getSp_prepay());
			dealings.setDl_date(DateUtil.getCurrentTime());
			dealings.setDl_manager(user.getUs_name());
			dealings.setDl_remark(fee.getFe_remark());
			dealings.setDl_sysdate(DateUtil.getCurrentTime());
			dealings.setCompanyid(user.getCompanyid());
			buyDealingsDAO.save(dealings);
		}
		return fee;
	}
	
	@Override
	@Transactional
	public T_Buy_Fee reverse(String number, T_Sys_User user) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Buy_Fee fee = buyFeeDAO.check(number, user.getCompanyid());
		if(fee == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_APPROVED.equals(fee.getFe_ar_state())){
			throw new RuntimeException("单据未审核或审核未通过");
		}
		if(!CommonUtil.PAY_STATE_UNPAY.equals(fee.getFe_pay_state())){
			throw new RuntimeException("该单据已经结算，不能反审核");
		}
		T_Buy_SettleList existSettle = buySettleDAO.check_settle_bill(fee.getFe_number(), user.getCompanyid());
		if(existSettle != null){
			throw new RuntimeException("该单据已经结算，结算单据["+existSettle.getStl_number()+"]，不能反审核");
		}
		//1.更新单据审核状态
		fee.setFe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		fee.setFe_ar_date(DateUtil.getCurrentTime());
		buyFeeDAO.updateApprove(fee);
		//2.保存审核记录表
		T_Approve_Record record = new T_Approve_Record();
		record.setAr_state(CommonUtil.AR_STATE_REVERSE_APPROVE);
		record.setAr_describe(user.getUs_name()+"反审核单据");
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_buy_fee");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		
		//3更新供应商财务&删除往来明细账
		T_Buy_Supply supply = supplyDAO.loadSupply(fee.getFe_supply_code(), user.getCompanyid());
		if (supply != null) {
			supply.setSp_payable(supply.getSp_payable() - fee.getFe_payable());
			supplyDAO.updatePayable(supply);
			T_Buy_Dealings dealings = new T_Buy_Dealings();
			dealings.setDl_supply_code(fee.getFe_supply_code());
			dealings.setDl_number(fee.getFe_number());
			dealings.setDl_type(CommonUtil.BUYDEALINGS_TYPE_FY);
			dealings.setDl_discount_money(-fee.getFe_discount_money());
			dealings.setDl_payable(-fee.getFe_payable());
			dealings.setDl_payabled(0d);
			dealings.setDl_debt(supply.getSp_payable()-supply.getSp_payabled()-supply.getSp_prepay());
			dealings.setDl_date(DateUtil.getCurrentTime());
			dealings.setDl_manager(user.getUs_name());
			dealings.setDl_remark("反审核恢复账目往来明细");
			dealings.setDl_sysdate(DateUtil.getCurrentTime());
			dealings.setCompanyid(user.getCompanyid());
			buyDealingsDAO.save(dealings);
		}
		return fee;
	}
	
	@Override
	@Transactional
	public void initUpdate(String number, Integer us_id, Integer companyid) {
		List<T_Buy_FeeList> details = buyFeeDAO.detail_list_forsavetemp(number, companyid);;
		for(T_Buy_FeeList item:details){
			item.setFel_us_id(us_id);
		}
		buyFeeDAO.temp_clear(us_id, companyid);
		buyFeeDAO.temp_save(details);
	}
	
	@Override
	@Transactional
	public void del(String number, Integer companyid) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Buy_Fee fee = buyFeeDAO.check(number, companyid);
		if(fee == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(fee.getFe_ar_state()) && !CommonUtil.AR_STATE_FAIL.equals(fee.getFe_ar_state())){
			throw new RuntimeException("单据已审核通过不能删除！");
		}
		buyFeeDAO.del(number, companyid);
	}
	
	@Override
	public Map<String, Object> loadPrintData(String number, Integer sp_id, T_Sys_User user) {
		Map<String, Object> resultMap = printDAO.loadPrint4Bill(sp_id);
		T_Buy_Fee fee = buyFeeDAO.load(number, user.getCompanyid());
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fel_number", number);
		params.put("companyid", user.getCompanyid());
		List<T_Buy_FeeList> feeList = buyFeeDAO.detail_list(params);
		resultMap.put("fee", fee);
		resultMap.put("feeList", feeList);
		resultMap.put("supply", supplyDAO.load(fee.getFe_supply_code(), user.getCompanyid()));
		return resultMap;
	}
	
	@Override
	public List<BuyFeeReportDto> listReport(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		return buyFeeDAO.listReport(params);
	}
	
	@Override
	public List<BuyFeeReportDto> listReportDetail(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		return buyFeeDAO.listReportDetail(params);
	}
	
}
